package comunicacion;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;
import menu.mensajero.Mensaje;
import menu.mensajero.Mensajero;
import menu.menu.Constantes;

/**
 * Clase que se encarga de la comunicación entre aplicaciones y delegates.
 * @author JSR
 * @version $Id: Comunicacion.java 60 2010-10-06 02:35:16Z batianusrey $
 */
public class Comunicacion
{
    //---------------------------------------
    // Constantes
    //---------------------------------------

    /**
     * Atributo que representa la ubicacion del servidor central. Puede ser el nombre del servidor o una dirección IP
     */
    private static final String SERVIDOR = "localhost";
    /**
     * Atributo que representa el puerto con el que se va a hacer la conexion en el servidor
     */
    private static final int PUERTO = 9999;
    //---------------------------------------
    // Atributos
    //---------------------------------------
    /**
     * Atributo del socket hacia el servidor
     */
    private Socket socket;
    /**
     * Atributo del canal de comunicación hacia el servidor
     */
    private PrintWriter salida;
    /**
     * Atributo del canal de comunicación desde el servidor
     */
    private BufferedReader entrada;
    /**
     * Atributo que representa el chat entre mesas
     */
    private Mensajero mensajero;

    //---------------------------------------
    // Constructor
    //---------------------------------------
    //---------------------------------------
    // Getters y Setters
    //---------------------------------------
    //---------------------------------------
    // Métodos
    //---------------------------------------
    /**
     * Metodo que inicia la conexion de cliente hacia el servidor central incluyendo el socket y los canales de lectura/escritura
     */
    private void iniciarCanales()
    {
        try {
            socket = new Socket( SERVIDOR, PUERTO );
            entrada = new BufferedReader( new InputStreamReader( socket.getInputStream() ) );
            salida = new PrintWriter( socket.getOutputStream(), true );
        } catch( UnknownHostException ex ) {
            Logger.getLogger( Comunicacion.class.getName() ).log( Level.SEVERE, null, ex );
            System.out.println( ex.getMessage() );
        } catch( IOException ex ) {
            Logger.getLogger( Comunicacion.class.getName() ).log( Level.SEVERE, null, ex );
            System.out.println( ex.getMessage() );
        }
    }

    /**
     * Metodo que inicia el thread de recibir mensajes desde el servidor
     */
    private void iniciarThreadRecibirServidor()
    {
        final ThreadRecibirServidor entradaServidor = new ThreadRecibirServidor( entrada, mensajero );
        Timer t = new Timer();
        t.schedule( new TimerTask()
        {

            public void run()
            {
                entradaServidor.start();
            }
        }, 500 );
    }

    //---------------------------------------
    // Métodos de comunicación
    //---------------------------------------
    /**
     * Metodo que envia un mensaje de chat al destino indicado
     * @param msj - Mensaje con sus atributos
     * @param destino - Mesa de destino del mensaje
     */
    public void enviarMensajeDeChat( Mensaje msj, String destino )
    {
        String protocoloMensaje = "MENSAJE::" + msj.getAutor() + "::" + destino + "::" + msj.getContenido() + "::" + ManejadorFormatoFechas.formatoFechaMensajero.format( darFechaActual() );
        salida.println( protocoloMensaje );
    }

    /**
     * Metodo que envia el pedido de la cuenta al sistema central
     * @param mesa - Mesa que pide la cuenta
     * @param pago - Tipo de pago para cancelar la cuenta
     */
    public void pedirCuenta( String mesa, Constantes.TipoPago pago )
    {
        String protocoloCuenta = "CUENTA::" + mesa + "::" + pago;
        salida.println( protocoloCuenta );
    }

    /**
     * Metodo que envia una sugerencia al sistema central
     * @param autor - autor de la sugerencia
     * @param email - email del autor
     * @param mesa - identificador de la mesa
     * @param comentario - Contenido de la sugerencia
     */
    public void enviarSugerencia( String autor, String email, String mesa, String comentario )
    {
        String protocoloSugerencia = "SUGERENCIA::" + autor + "::" + email + "::" + mesa + "::" + comentario + "::" + ManejadorFormatoFechas.formatoFechaSugerencia.format( darFechaActual() );
        salida.println( protocoloSugerencia );
    }

    /**
     * Metodo que permite llamar un mesero a la mesa indicada
     * @param mesa - Identificador de la mesa
     */
    public void llamarMesero( String mesa )
    {
        String protocoloLlamarMesero = "MESERO::" + mesa;
        salida.println( protocoloLlamarMesero );
    }

    //---------------------------------------
    // Métodos de comunicación
    //---------------------------------------
    /**
     * Da la fecha actual del sistema
     * @return fechaActual - La fecha actual del sistema
     */
    public Date darFechaActual()
    {
        return new Date( System.currentTimeMillis() );
    }
}
